﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;
using ICSharpCode.SharpZipLib.BZip2;
using ICSharpCode.SharpZipLib.Tar;
using SevenZip;
using System.Reflection;

namespace Super64
{
    public static class ArchiveTools
    {
        public static IEnumerable<GameListEntry> GetZipEntries(string file, string[] filters)
        {
            List<GameListEntry> gameEntries = new List<GameListEntry>();

            using (FileStream f = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                ZipFile zip = new ZipFile(f);

                for (long i = 0; i < zip.Count; i++)
                {
                    string fname = zip[(int)i].Name;

                    if (filters.Contains(Path.GetExtension(fname.ToLower())))
                    {
                        GameListEntry entry = new GameListEntry(file, fname + "|" + i.ToString(), 0);
                        entry.Name = Path.GetFileNameWithoutExtension(fname);
                        gameEntries.Add(entry);
                    }
                }
            }

            return gameEntries;
        }

        public static Stream DecompressBZip2(Stream input)
        {
            MemoryStream decStream = new MemoryStream();
            BZip2.Decompress(input, decStream, false);
            return decStream;
        }

        public static Stream DecompressZipEntry(GameListEntry entry)
        {
            // Get the URI parts
            string[] parts = entry.URIPath.Split('|');

            //  Get the rom file name
            string fname = parts[0];

            // Get the index of the zip entry
            int zipEntryIndex = int.Parse(parts[1]);

            // TODO: Handle if the zip contents chagned and loop for the URI name

            // Decompress it
            ZipFile zip = new ZipFile(entry.FilePath);
            MemoryStream memStream = new MemoryStream();
            zip.GetInputStream((long)zipEntryIndex).CopyTo(memStream);
            memStream.Position = 0;
            return memStream;
        }

        public static Stream DecompressBzip2(GameListEntry entry)
        {
            using (FileStream f = new FileStream(entry.FilePath, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
              return DecompressBZip2(f);
            }
        }

        public static IEnumerable<GameListEntry> Get7zipEntries(string file, string[] filters)
        {
            List<GameListEntry> gameEntries = new List<GameListEntry>();

            using (FileStream f = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                SevenZipExtractor zip = new SevenZipExtractor(f);

                foreach (string fname in zip.ArchiveFileNames)
                {
                    if (filters.Contains(Path.GetExtension(fname.ToLower())))
                    {
                        GameListEntry entry = new GameListEntry(file, fname, 0);
                        entry.Name = Path.GetFileNameWithoutExtension(fname);
                        gameEntries.Add(entry);
                    }
                }
            }

            return gameEntries;
        }

        public static Stream Decompress7ZipEntry(GameListEntry entry)
        {
            MemoryStream mem = new MemoryStream();

            using (FileStream f = new FileStream(entry.FilePath, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                SevenZipExtractor zip = new SevenZipExtractor(f);
                zip.ExtractFile(entry.URIPath, mem);
                return mem;
            }
        }
    }
}
